package li.kaeppe.travel.tracker.dao;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import li.kaeppe.travel.tracker.domain.Trip;
import li.kaeppe.travel.tracker.service.TripIdCreator;

public class HibernateTripDaoImpl implements TripDao {

	/* **************************************************** */
	/*                      CONSTANTS                       */
	/* **************************************************** */

	private static final Log log = LogFactory
			.getLog(HibernateTripDaoImpl.class);

	/* **************************************************** */
	/*                     MEMBER FIELDS                    */
	/* **************************************************** */
	
	private SessionFactory sessionFactory;
	
	private TripIdCreator uuidGenerator;
	
	/* **************************************************** */
	/*                      CONSTRUCTOR                     */
	/* **************************************************** */

	/* **************************************************** */
	/*                    PUBLIC METHODS                    */
	/* **************************************************** */

	public void deleteTrip(Trip trip) {
		if(log.isDebugEnabled()) {
			log.debug("HibernateTripDaoImpl -> deleteTrip()");
		}
		
		this.getSession().delete(trip);
	}

	@SuppressWarnings("unchecked")
	public List<Trip> getAllTrips() {
		if(log.isDebugEnabled()) {
			log.debug("HibernateTripDaoImpl -> getAllTrips()");
		}
		
		List<Trip> trips = this.getSession().createQuery("from Trip").list();
		return trips;
	}

	public Trip storeTrip(Trip trip) {
		if(trip.getKey() == null) {
			trip.setKey(this.getUuidGenerator().generateTripId(trip));
		}
		if(log.isDebugEnabled()) {
			log.debug("HibernateTripDaoImpl -> storeTrip() with key [" +
						trip.getKey() + "]");
		}
		this.getSession().saveOrUpdate(trip);
		return trip;
	}
	
	public Trip getTripById(long id) {
		if(log.isDebugEnabled()) {
			log.debug("HibernateTripDaoImpl -> getTrip()");
		}
		Query query = this.getSession().createQuery("from Trip t where t.id = :id");
		query.setLong("id", id);
		return (Trip)query.uniqueResult();
	}
	
	public Trip getTripByKey(String key) {
		if(log.isDebugEnabled()) {
			log.debug("HibernateTripDaoImpl -> getTripByKey()");
		}
		Query query = this.getSession().createQuery("from Trip t where t.key = :key");
		query.setString("key", key);
		return (Trip)query.uniqueResult();	
	}
	
	/* **************************************************** */
	/*                  PROTECTED METHODS                   */
	/* **************************************************** */

	/* **************************************************** */
	/*                   PRIVATE METHODS                    */
	/* **************************************************** */

	private Session getSession() {
		return this.getSessionFactory().getCurrentSession();
	}
	
	/* **************************************************** */
	/*                  GETTERS AND SETTERS                 */
	/* **************************************************** */
	
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	
	public TripIdCreator getUuidGenerator() {
		return uuidGenerator;
	}

	public void setUuidGenerator(TripIdCreator uuidGenerator) {
		this.uuidGenerator = uuidGenerator;
	}
}
